from functools import wraps
from flask import request, current_app
from flask_jwt_extended import get_jwt_identity
from ..services.user_service import UserService
from ..services.role_service import RoleService
from ..utils.response import error_response

def check_permission():
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            try:
                # 获取当前用户ID
                user_id = get_jwt_identity()
                if not user_id:
                    return error_response(message="未授权访问", code=401)
                
                # 获取请求路径和方法
                path = request.path
                method = request.method.upper()
                
                # 构造当前请求的权限格式
                current_permission = f"{method}:{path}"
                
                # 获取用户的所有角色
                user_roles = UserService.get_user_roles(user_id)
                if not user_roles:
                    return error_response(message="用户没有任何角色", code=403)
                
                # 获取所有角色的权限
                has_permission = False
                for role in user_roles:
                    permissions = RoleService.get_role_permissions(role.id)
                    for perm in permissions:
                        # 检查权限是否匹配当前请求
                        # 支持通配符 *，例如：GET:* 或 *:/api/v1/users
                        perm_method, perm_path = perm.resource_path.split(':', 1)
                        
                        if (perm_method == '*' or perm_method == method) and \
                           (perm_path == '*' or perm_path == path):
                            has_permission = True
                            break
                    if has_permission:
                        break
                
                if not has_permission:
                    current_app.logger.warning(
                        f"权限检查失败: 用户 {user_id} 尝试访问 {current_permission}"
                    )
                    return error_response(message="没有访问权限", code=403)
                
                return fn(*args, **kwargs)
            
            except Exception as e:
                current_app.logger.error(f"权限检查失败: {str(e)}")
                return error_response(message="权限检查失败", code=500)
        
        return wrapper
    return decorator 